1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.primitives;
18
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static com.google.common.base.Preconditions.checkElementIndex;
21 import static com.google.common.base.Preconditions.checkNotNull;
22 import static com.google.common.base.Preconditions.checkPositionIndexes;
23
24 import com.google.common.annotations.GwtCompatible;
25
26 import java.io.Serializable;
27 import java.util.AbstractList;
28 import java.util.Arrays;
29 import java.util.Collection;
30 import java.util.Collections;
31 import java.util.List;
32 import java.util.RandomAccess;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 @GwtCompatible
51 public final class Bytes {
52 private Bytes() {}
53
54
55
56
57
58
59
60
61 public static int hashCode(byte value) {
62 return value;
63 }
64
65
66
67
68
69
70
71
72
73
74 public static boolean contains(byte[] array, byte target) {
75 for (byte value : array) {
76 if (value == target) {
77 return true;
78 }
79 }
80 return false;
81 }
82
83
84
85
86
87
88
89
90
91
92 public static int indexOf(byte[] array, byte target) {
93 return indexOf(array, target, 0, array.length);
94 }
95
96
97 private static int indexOf(
98 byte[] array, byte target, int start, int end) {
99 for (int i = start; i < end; i++) {
100 if (array[i] == target) {
101 return i;
102 }
103 }
104 return -1;
105 }
106
107
108
109
110
111
112
113
114
115
116
117
118 public static int indexOf(byte[] array, byte[] target) {
119 checkNotNull(array, "array");
120 checkNotNull(target, "target");
121 if (target.length == 0) {
122 return 0;
123 }
124
125 outer:
126 for (int i = 0; i < array.length - target.length + 1; i++) {
127 for (int j = 0; j < target.length; j++) {
128 if (array[i + j] != target[j]) {
129 continue outer;
130 }
131 }
132 return i;
133 }
134 return -1;
135 }
136
137
138
139
140
141
142
143
144
145
146 public static int lastIndexOf(byte[] array, byte target) {
147 return lastIndexOf(array, target, 0, array.length);
148 }
149
150
151 private static int lastIndexOf(
152 byte[] array, byte target, int start, int end) {
153 for (int i = end - 1; i >= start; i--) {
154 if (array[i] == target) {
155 return i;
156 }
157 }
158 return -1;
159 }
160
161
162
163
164
165
166
167
168
169
170 public static byte[] concat(byte[]... arrays) {
171 int length = 0;
172 for (byte[] array : arrays) {
173 length += array.length;
174 }
175 byte[] result = new byte[length];
176 int pos = 0;
177 for (byte[] array : arrays) {
178 System.arraycopy(array, 0, result, pos, array.length);
179 pos += array.length;
180 }
181 return result;
182 }
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200 public static byte[] ensureCapacity(
201 byte[] array, int minLength, int padding) {
202 checkArgument(minLength >= 0, "Invalid minLength: %s", minLength);
203 checkArgument(padding >= 0, "Invalid padding: %s", padding);
204 return (array.length < minLength)
205 ? copyOf(array, minLength + padding)
206 : array;
207 }
208
209
210 private static byte[] copyOf(byte[] original, int length) {
211 byte[] copy = new byte[length];
212 System.arraycopy(original, 0, copy, 0, Math.min(original.length, length));
213 return copy;
214 }
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231 public static byte[] toArray(Collection<? extends Number> collection) {
232 if (collection instanceof ByteArrayAsList) {
233 return ((ByteArrayAsList) collection).toByteArray();
234 }
235
236 Object[] boxedArray = collection.toArray();
237 int len = boxedArray.length;
238 byte[] array = new byte[len];
239 for (int i = 0; i < len; i++) {
240
241 array[i] = ((Number) checkNotNull(boxedArray[i])).byteValue();
242 }
243 return array;
244 }
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260 public static List<Byte> asList(byte... backingArray) {
261 if (backingArray.length == 0) {
262 return Collections.emptyList();
263 }
264 return new ByteArrayAsList(backingArray);
265 }
266
267 @GwtCompatible
268 private static class ByteArrayAsList extends AbstractList<Byte>
269 implements RandomAccess, Serializable {
270 final byte[] array;
271 final int start;
272 final int end;
273
274 ByteArrayAsList(byte[] array) {
275 this(array, 0, array.length);
276 }
277
278 ByteArrayAsList(byte[] array, int start, int end) {
279 this.array = array;
280 this.start = start;
281 this.end = end;
282 }
283
284 @Override public int size() {
285 return end - start;
286 }
287
288 @Override public boolean isEmpty() {
289 return false;
290 }
291
292 @Override public Byte get(int index) {
293 checkElementIndex(index, size());
294 return array[start + index];
295 }
296
297 @Override public boolean contains(Object target) {
298
299 return (target instanceof Byte)
300 && Bytes.indexOf(array, (Byte) target, start, end) != -1;
301 }
302
303 @Override public int indexOf(Object target) {
304
305 if (target instanceof Byte) {
306 int i = Bytes.indexOf(array, (Byte) target, start, end);
307 if (i >= 0) {
308 return i - start;
309 }
310 }
311 return -1;
312 }
313
314 @Override public int lastIndexOf(Object target) {
315
316 if (target instanceof Byte) {
317 int i = Bytes.lastIndexOf(array, (Byte) target, start, end);
318 if (i >= 0) {
319 return i - start;
320 }
321 }
322 return -1;
323 }
324
325 @Override public Byte set(int index, Byte element) {
326 checkElementIndex(index, size());
327 byte oldValue = array[start + index];
328
329 array[start + index] = checkNotNull(element);
330 return oldValue;
331 }
332
333 @Override public List<Byte> subList(int fromIndex, int toIndex) {
334 int size = size();
335 checkPositionIndexes(fromIndex, toIndex, size);
336 if (fromIndex == toIndex) {
337 return Collections.emptyList();
338 }
339 return new ByteArrayAsList(array, start + fromIndex, start + toIndex);
340 }
341
342 @Override public boolean equals(Object object) {
343 if (object == this) {
344 return true;
345 }
346 if (object instanceof ByteArrayAsList) {
347 ByteArrayAsList that = (ByteArrayAsList) object;
348 int size = size();
349 if (that.size() != size) {
350 return false;
351 }
352 for (int i = 0; i < size; i++) {
353 if (array[start + i] != that.array[that.start + i]) {
354 return false;
355 }
356 }
357 return true;
358 }
359 return super.equals(object);
360 }
361
362 @Override public int hashCode() {
363 int result = 1;
364 for (int i = start; i < end; i++) {
365 result = 31 * result + Bytes.hashCode(array[i]);
366 }
367 return result;
368 }
369
370 @Override public String toString() {
371 StringBuilder builder = new StringBuilder(size() * 5);
372 builder.append('[').append(array[start]);
373 for (int i = start + 1; i < end; i++) {
374 builder.append(", ").append(array[i]);
375 }
376 return builder.append(']').toString();
377 }
378
379 byte[] toByteArray() {
380
381 int size = size();
382 byte[] result = new byte[size];
383 System.arraycopy(array, start, result, 0, size);
384 return result;
385 }
386
387 private static final long serialVersionUID = 0;
388 }
389 }